#!/bin/bash

_is_root() {
    if [ "$(id -u)" -eq 0 ]; then
        return 0
    else
        return 1
    fi
}

_is_china() {
    if ${IN_CHINA:-false} || ${CHANGE_SOURCE:-false}; then
        return 0
    else
        return 1
    fi
}

_set_mirror() {
    if [ "$1" = shanghai ]; then
        export TZ=Asia/Shanghai
        ln -snf /usr/share/zoneinfo/"${TZ}" /etc/localtime
        echo "${TZ}" >/etc/timezone
        return
    fi

    url_fly_cdn="http://oss.flyh6.com/d"

    if command -v apt-get; then
        cmd_pkg=apt-get
        cmd_pkg_opt="$cmd_pkg install -yqq --no-install-recommends"
        update_cache=true
    elif command -v yum; then
        cmd_pkg=yum
        cmd_pkg_opt="$cmd_pkg install -y --setopt=tsflags=nodocs"
    elif command -v apk; then
        cmd_pkg=apk
        cmd_pkg_opt="$cmd_pkg add --no-cache"
    fi

    if _is_china; then
        url_deploy_raw=https://gitee.com/xiagw/deploy.sh/raw/main
        url_laradock_raw=https://gitee.com/xiagw/laradock/raw/in-china
    else
        url_deploy_raw=https://github.com/xiagw/deploy.sh/raw/main
        url_laradock_raw=https://github.com/xiagw/laradock/raw/main
        return
    fi

    if _is_root; then
        ## OS ubuntu:22.04 php
        if [ -f /etc/apt/sources.list ]; then
            sed -i -e 's/deb.debian.org/mirrors.ustc.edu.cn/g' \
                -e 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
        ## OS Debian
        elif [ -f /etc/apt/sources.list.d/debian.sources ]; then
            sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list.d/debian.sources
        ## OS alpine, nginx:alpine
        elif [ -f /etc/apk/repositories ]; then
            # sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/' /etc/apk/repositories
            sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories
        fi
    fi

    if command -v mvn; then
        local m2_dir=/root/.m2
        [ -d $m2_dir ] || mkdir -p $m2_dir
        ## 项目内自带 settings.xml docs/settings.xml
        if [ -f settings.xml ]; then
            cp -vf settings.xml $m2_dir/
        elif [ -f docs/settings.xml ]; then
            cp -vf docs/settings.xml $m2_dir/
        elif [ -f /opt/settings.xml ]; then
            mv -vf /opt/settings.xml $m2_dir/
        else
            curl -Lo $m2_dir/settings.xml $url_deploy_raw/conf/dockerfile/root/opt/settings.xml
        fi
    elif command -v composer; then
        _is_root || return
        composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
        mkdir -p /var/www/.composer /.composer
        chown -R 1000:1000 /var/www/.composer /.composer /tmp/cache /tmp/config.json /tmp/auth.json
    elif command -v node; then
        # npm_mirror=https://mirrors.ustc.edu.cn/node/
        # npm_mirror=http://mirrors.cloud.tencent.com/npm/
        # npm_mirror=https://mirrors.huaweicloud.com/repository/npm/
        npm_mirror=https://registry.npmmirror.com/
        yarn config set registry $npm_mirror
        npm config set registry $npm_mirror
    elif command -v python || command -v python3; then
        if command -v java; then
            return
        fi
        pip_mirror=https://pypi.tuna.tsinghua.edu.cn/simple
        if command -v python3; then
            python3 -m pip config set global.index-url $pip_mirror
        else
            python -m pip config set global.index-url $pip_mirror
        fi
    fi
}

_check_run_sh() {
    if [ -f "$run_sh" ]; then
        echo "Found $run_sh, skip download."
    else
        echo "Not found $run_sh, download..."
        curl -fLo $run_sh "$url_deploy_raw"/conf/dockerfile/root$run_sh
    fi
    chmod +x $run_sh
}

_build_nginx() {
    echo "build nginx:alpine..."
    $cmd_pkg update
    $cmd_pkg upgrade
    $cmd_pkg_opt openssl bash curl shadow
    touch /var/log/messages

    groupmod -g 1000 nginx
    usermod -u 1000 nginx
}

_build_php() {
    echo "build php ..."
    _set_mirror shanghai
    if ${update_cache:-false}; then
        $cmd_pkg update -yqq
    fi
    # $cmd_pkg_opt libjemalloc2
    $cmd_pkg_opt apt-utils
    # $cmd_pkg_opt libterm-readkey-perl
    $cmd_pkg_opt vim curl ca-certificates
    # $cmd_pkg_opt language-pack-en-base

    ## preesed tzdata, update package index, upgrade packages and install needed software
    (
        echo "tzdata tzdata/Areas select Asia"
        echo "tzdata tzdata/Zones/Asia select Shanghai"
    ) >/tmp/preseed.cfg
    debconf-set-selections /tmp/preseed.cfg
    rm -f /etc/timezone /etc/localtime

    export DEBIAN_FRONTEND=noninteractive
    export DEBCONF_NONINTERACTIVE_SEEN=true

    $cmd_pkg_opt tzdata
    $cmd_pkg_opt locales
    # $cmd_pkg_opt language-pack-en-base

    if ! grep '^en_US.UTF-8' /etc/locale.gen; then
        echo 'en_US.UTF-8 UTF-8' >>/etc/locale.gen
    fi
    locale-gen en_US.UTF-8

    case "$PHP_VERSION" in
    8.1)
        echo "install PHP from repo of OS..."
        ;;
    *)
        echo "install PHP from ppa:ondrej/php..."
        $cmd_pkg_opt lsb-release gnupg2 ca-certificates apt-transport-https software-properties-common
        LC_ALL=C.UTF-8 LANG=C.UTF-8 add-apt-repository -y ppa:ondrej/php
        case "$PHP_VERSION" in
        8.3) $cmd_pkg_opt php"${PHP_VERSION}"-common ;;
        8.*) : ;;
        *) $cmd_pkg_opt php"${PHP_VERSION}"-mcrypt ;;
        esac
        ;;
    esac

    $cmd_pkg upgrade -yqq
    $cmd_pkg_opt \
        php"${PHP_VERSION}" \
        php"${PHP_VERSION}"-bcmath \
        php"${PHP_VERSION}"-bz2 \
        php"${PHP_VERSION}"-curl \
        php"${PHP_VERSION}"-fpm \
        php"${PHP_VERSION}"-gd \
        php"${PHP_VERSION}"-gmp \
        php"${PHP_VERSION}"-imagick \
        php"${PHP_VERSION}"-intl \
        php"${PHP_VERSION}"-mbstring \
        php"${PHP_VERSION}"-mongodb \
        php"${PHP_VERSION}"-msgpack \
        php"${PHP_VERSION}"-mysql \
        php"${PHP_VERSION}"-redis \
        php"${PHP_VERSION}"-soap \
        php"${PHP_VERSION}"-sqlite3 \
        php"${PHP_VERSION}"-xml \
        php"${PHP_VERSION}"-xmlrpc \
        php"${PHP_VERSION}"-zip

    # php"${PHP_VERSION}"-process \
    # php"${PHP_VERSION}"-pecl-mcrypt  replace by  php"${PHP_VERSION}"-libsodium

    case "$PHP_VERSION" in
    5.6)
        $cmd_pkg_opt apache2 libapache2-mod-fcgid libapache2-mod-php"${PHP_VERSION}"
        sed -i -e '1 i ServerTokens Prod' -e '1 i ServerSignature Off' -e '1 i ServerName www.example.com' /etc/apache2/sites-available/000-default.conf
        ;;
    *)
        $cmd_pkg_opt nginx
        ;;
    esac
    # $cmd_pkg_opt lsyncd openssh-client

    sed -i \
        -e '/fpm.sock/s/^/;/' \
        -e '/fpm.sock/a listen = 9000' \
        -e '/rlimit_files/a rlimit_files = 65535' \
        -e '/pm.max_children/s/5/10000/' \
        -e '/pm.start_servers/s/2/10/' \
        -e '/pm.min_spare_servers/s/1/10/' \
        -e '/pm.max_spare_servers/s/3/20/' \
        -e '/^;slowlog.*log\//s//slowlog = \/var\/log\/php/' \
        -e '/^;request_slowlog_timeout.*/s//request_slowlog_timeout = 2/' \
        /etc/php/"${PHP_VERSION}"/fpm/pool.d/www.conf
    sed -i \
        -e "/memory_limit/s/128M/1024M/" \
        -e "/post_max_size/s/8M/1024M/" \
        -e "/upload_max_filesize/s/2M/1024M/" \
        -e "/max_file_uploads/s/20/1024/" \
        -e '/disable_functions/s/$/phpinfo,/' \
        -e '/max_execution_time/s/30/60/' \
        /etc/php/"${PHP_VERSION}"/fpm/php.ini
    sed -i \
        -e '/^;slowlog.*log\//s//slowlog = \/var\/log\/php/' \
        -e '/^;request_slowlog_timeout.*/s//request_slowlog_timeout = 2/' \
        /etc/php/"${PHP_VERSION}"/fpm/pool.d/www.conf
}

_onbuild_php() {
    if command -v php && [ -n "$PHP_VERSION" ]; then
        php -v
    else
        return
    fi

    if [ "$PHP_SESSION_REDIS" = true ]; then
        sed -i -e "/session.save_handler/s/files/redis/" \
            -e "/session.save_handler/a session.save_path = \"tcp://${PHP_SESSION_REDIS_SERVER}:${PHP_SESSION_REDIS_PORT}?auth=${PHP_SESSION_REDIS_PASS}&database=${PHP_SESSION_REDIS_DB}\"" \
            /etc/php/"${PHP_VERSION}"/fpm/php.ini
    fi

    ## setup nginx for ThinkPHP
    curl -fLo /etc/nginx/sites-enabled/default "$url_laradock_raw"/php-fpm/root/opt/nginx.conf

    _check_run_sh
}

_build_node() {
    echo "build node ..."

    $cmd_pkg update -yqq
    $cmd_pkg_opt less vim curl ca-certificates
    [ -d /.cache ] || mkdir /.cache
    [ -d /app ] || mkdir /app
    chown -R node:node /.cache /app
    npm install -g npm
    _is_china && npm install -g cnpm

    if _is_china; then
        su -l node -c "cd /app && cnpm install"
    else
        su -l node -c "cd /app && npm install"
    fi
    rm -rf root/ || :
}

_build_maven() {
    # --settings=settings.xml --activate-profiles=main
    # mvn -T 1C install -pl $moduleName -am --offline
    if [ "$MVN_DEBUG" = on ]; then
        mvn_opt="mvn"
    else
        mvn_opt="mvn --quiet"
    fi
    $mvn_opt --threads 1C --update-snapshots -DskipTests -Dmaven.compile.fork=true clean package

    mkdir /jars
    while read -r jar; do
        [ -f "$jar" ] || continue
        echo "$jar" | grep -E 'framework.*|gdp-module.*|sdk.*\.jar|.*-commom-.*\.jar|.*-dao-.*\.jar|lop-opensdk.*\.jar|core-.*\.jar' ||
            cp -vf "$jar" /jars/
    done < <(
        find ./target/*.jar ./*/target/*.jar ./*/*/target/*.jar 2>/dev/null
    )
    if [[ "${MVN_COPY_YAML:-false}" == true ]]; then
        unset c
        while read -r yml; do
            [ -f "$yml" ] || continue
            ((++c))
            cp -vf "$yml" /jars/"${c}.${yml##*/}"
        done < <(
            find ./*/*/*/*"${MVN_PROFILE:-main}".yml ./*/*/*/*"${MVN_PROFILE:-main}".yaml 2>/dev/null
        )
    fi
}

_build_jdk_runtime() {
    if ${INSTALL_JEMALLOC:-false}; then
        if ${update_cache:-false}; then
            $cmd_pkg update -yqq
            # $cmd_pkg less apt-utils
            $cmd_pkg install -yqq libjemalloc2
        else
            $cmd_pkg install -y memkind
        fi
    fi
    if ${INSTALL_FFMPEG:-false}; then
        ${update_cache:-false} && $cmd_pkg update -yqq
        $cmd_pkg_opt ffmpeg
    fi
    if ${INSTALL_LIBREOFFICE:-false}; then
        ${update_cache:-false} && $cmd_pkg update -yqq
        $cmd_pkg_opt libreoffice
    fi
    if ${INSTALL_REDIS:-false}; then
        ${update_cache:-false} && $cmd_pkg update -yqq
        $cmd_pkg_opt redis-server
    fi
    if ${INSTALL_FONTS:-false}; then
        ${update_cache:-false} && $cmd_pkg update -yqq
        $cmd_pkg_opt fontconfig
        curl --referer "$url_fly_cdn" -Lo /tmp/fonts.zip "$url_fly_cdn"/fonts.zip
        cd /usr/share/fonts && unzip -o /tmp/fonts.zip
        fc-cache -fv
    fi
    ## set ssl
    file1=/usr/lib/jvm/java-17-amazon-corretto/conf/security/java.security
    file2=/usr/lib/jvm/java-1.8.0-amazon-corretto/jre/lib/security/java.security
    file3=/usr/local/openjdk-8/jre/lib/security/java.security
    for file in $file1 $file2 $file3; do
        if [[ -f $file ]]; then
            sed -i 's/SSLv3\,\ TLSv1\,\ TLSv1\.1\,//g' "$file"
        fi
    done

    _check_run_sh
    [ -d /app ] || mkdir /app
    command -v su || $cmd_pkg install -y util-linux
    command -v useradd || yum install -y shadow-utils
    useradd -u 1000 -s /bin/bash -m spring
    chown -R 1000:1000 /app
    for file in /app/*.{yml,yaml}; do
        if [ -f "$file" ]; then
            break
        else
            touch "/app/profile.${MVN_PROFILE:-main}"
        fi
    done
}

_build_python() {
    echo TODO...
    return 1
}

_build_mysql() {
    echo "build mysql ..."
    chown -R mysql:root /var/lib/mysql/
    chmod o-rw /var/run/mysqld

    my_cnf=/etc/mysql/conf.d/my.cnf
    if mysqld --version | grep '8\..\.'; then
        cp -f "$me_path"/my.8.cnf $my_cnf
    else
        cp -f "$me_path"/my.cnf $my_cnf
    fi
    chmod 0444 $my_cnf
    if [ "$MYSQL_SLAVE" = 'true' ]; then
        sed -i -e "/server_id/s/1/${MYSQL_SLAVE_ID:-2}/" -e "/auto_increment_offset/s/1/2/" $my_cnf
    fi
    if [ -f /etc/my.cnf ]; then
        sed -i '/skip-host-cache/d' /etc/my.cnf
    fi

    printf "[client]\npassword=%s\n" "${MYSQL_ROOT_PASSWORD}" >"$HOME"/.my.cnf
    printf "export LANG=C.UTF-8\alias l='ls -al'" >"$HOME"/.bashrc

    chmod +x /opt/*.sh
}

_build_redis() {
    echo "build redis ..."
    if [ -f /etc/redis.conf ] && [ -n "${REDIS_PASSWORD}" ]; then
        sed -i -e "s/.*requirepass foobared/requirepass ${REDIS_PASSWORD}/" /etc/redis.conf
    fi
    mkdir /run/redis
    chown redis:redis /run/redis
}

_build_tomcat() {
    # FROM bitnami/tomcat:8.5 as tomcat
    sed -i -e '/Connector port="8080"/ a maxConnections="800" acceptCount="500" maxThreads="400"' /opt/bitnami/tomcat/conf/server.xml
    # && sed -i -e '/UMASK/s/0027/0022/' /opt/bitnami/tomcat/bin/catalina.sh
    sed -i -e '/localhost_access_log/ a rotatable="false"' /opt/bitnami/tomcat/conf/server.xml
    sed -i -e '/AsyncFileHandler.prefix = catalina./ a 1catalina.org.apache.juli.AsyncFileHandler.suffix = out\n1catalina.org.apache.juli.AsyncFileHandler.rotatable = False' /opt/bitnami/tomcat/conf/logging.properties
    ln -sf /dev/stdout /opt/bitnami/tomcat/logs/app-all.log
    # && ln -sf /dev/stdout /opt/bitnami/tomcat/logs/app-debug.log
    # && ln -sf /dev/stdout /opt/bitnami/tomcat/logs/app-info.log
    # && ln -sf /dev/stdout /opt/bitnami/tomcat/logs/app-error.log
    ln -sf /dev/stdout /opt/bitnami/tomcat/logs/catalina.out
    ln -sf /dev/stdout /opt/bitnami/tomcat/logs/localhost_access_log.txt
    # && useradd -m -s /bin/bash -u 1001 tomcat
    # && chown -R 1001 /opt/bitnami/tomcat
    rm -rf /opt/bitnami/tomcat/webapps_default/*
}

main() {
    set -xe
    # set -eo pipefail
    # shopt -s nullglob

    me_name="$(basename "$0")"
    me_path="$(dirname "$(readlink -f "$0")")"
    if [ -w "$me_path" ]; then
        me_log="$me_path/${me_name}.log"
    else
        me_log="/tmp/${me_name}.log"
    fi

    run_sh=/opt/run.sh
    echo "build log file: $me_log"

    _set_mirror

    case "$1" in
    --onbuild | onbuild)
        _onbuild_php
        return 0
        ;;
    esac

    if command -v nginx; then
        _build_nginx
    elif command -v composer; then
        _build_composer
    elif [ -n "$PHP_VERSION" ]; then
        _build_php
    elif command -v mvn; then
        _build_maven
    elif command -v java; then
        _build_jdk_runtime
    elif command -v node; then
        _build_node
    elif command -v python; then
        _build_python
    elif command -v mysql; then
        _build_mysql
    fi

    ## clean
    if _is_root; then
        if ${update_cache:-false}; then
            $cmd_pkg autoremove -y
            $cmd_pkg clean all
            rm -rf /var/lib/apt/lists/*
        fi
        if [ -d /var/cache/yum ]; then
            rm -rf /var/cache/yum
        fi
        rm -rf /tmp/* /opt/*.{cnf,xml,log}
    else
        :
    fi
}

main "$@"
